package com.ruoyi.system.service.impl;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.stereotype.Service;
import com.ruoyi.system.service.IOjPracticeService;
import com.ruoyi.system.domain.OjProblem;
import com.ruoyi.system.domain.OjSubmission;
import java.math.BigDecimal;

/**
 * OJ在线练习Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-01-21
 */
@Service
public class OjPracticeServiceImpl implements IOjPracticeService 
{
    // 临时存储数据，实际项目中应该使用数据库
    private final Map<String, OjProblem> problemMap = new ConcurrentHashMap<>();
    private final Map<String, OjSubmission> submissionMap = new ConcurrentHashMap<>();
    private long submissionIdCounter = 1;

    public OjPracticeServiceImpl() {
        // 初始化一些示例数据
        initializeSampleData();
    }

    private void initializeSampleData() {
        // 添加示例题目
        OjProblem problem1 = new OjProblem();
        problem1.setProblemId("P1001");
        problem1.setProblemName("两数之和");
        problem1.setProblemDescription("给定一个整数数组 nums 和一个整数目标值 target，请你在该数组中找出和为目标值 target 的那两个整数，并返回它们的数组下标。");
        problem1.setInputFormat("第一行输入一个整数 n，表示数组长度\n第二行输入 n 个整数，表示数组元素\n第三行输入一个整数 target，表示目标值");
        problem1.setOutputFormat("输出两个整数，表示满足条件的数组下标");
        problem1.setDifficulty("简单");
        problem1.setScore(new BigDecimal("10"));
        problem1.setTimeLimit(1000);
        problem1.setMemoryLimit(128);
        problem1.setCategory("基础算法");
        problem1.setTags("数组,哈希表");
        problem1.setSubmissionCount(156);
        problem1.setAcceptedCount(89);
        problem1.setAcceptanceRate(new BigDecimal("57.1"));
        problem1.setStatus("启用");
        problem1.setCreatedAt(new Date());
        problem1.setUpdatedAt(new Date());
        problemMap.put(problem1.getProblemId(), problem1);

        OjProblem problem2 = new OjProblem();
        problem2.setProblemId("P1002");
        problem2.setProblemName("最长回文子串");
        problem2.setProblemDescription("给你一个字符串 s，找到 s 中最长的回文子串。");
        problem2.setInputFormat("输入一个字符串 s");
        problem2.setOutputFormat("输出最长的回文子串");
        problem2.setDifficulty("中等");
        problem2.setScore(new BigDecimal("15"));
        problem2.setTimeLimit(2000);
        problem2.setMemoryLimit(256);
        problem2.setCategory("动态规划");
        problem2.setTags("字符串,动态规划");
        problem2.setSubmissionCount(89);
        problem2.setAcceptedCount(45);
        problem2.setAcceptanceRate(new BigDecimal("50.6"));
        problem2.setStatus("启用");
        problem2.setCreatedAt(new Date());
        problem2.setUpdatedAt(new Date());
        problemMap.put(problem2.getProblemId(), problem2);

        // 添加示例提交记录
        OjSubmission submission1 = new OjSubmission();
        submission1.setSubmissionId("S1001");
        submission1.setUserId("student001");
        submission1.setProblemId("P1001");
        submission1.setCode("#include <iostream>\n#include <vector>\n#include <unordered_map>\nusing namespace std;\n\nint main() {\n    int n, target;\n    cin >> n;\n    vector<int> nums(n);\n    for(int i = 0; i < n; i++) {\n        cin >> nums[i];\n    }\n    cin >> target;\n    \n    unordered_map<int, int> map;\n    for(int i = 0; i < n; i++) {\n        int complement = target - nums[i];\n        if(map.count(complement)) {\n            cout << map[complement] << \" \" << i << endl;\n            return 0;\n        }\n        map[nums[i]] = i;\n    }\n    cout << \"-1 -1\" << endl;\n    return 0;\n}");
        submission1.setLanguage("cpp");
        submission1.setStatus("已完成");
        submission1.setExecutionTime(15);
        submission1.setMemoryUsage(new BigDecimal("8.5"));
        submission1.setTestCasesPassed(10);
        submission1.setTotalTestCases(10);
        submission1.setScore(new BigDecimal("10"));
        submission1.setSubmissionType("practice");
        submission1.setEnableO2("是");
        submission1.setSubmissionTime(new Date());
        submission1.setJudgedTime(new Date());
        submissionMap.put(submission1.getSubmissionId(), submission1);

        OjSubmission submission2 = new OjSubmission();
        submission2.setSubmissionId("S1002");
        submission2.setUserId("student002");
        submission2.setProblemId("P1001");
        submission2.setCode("public class Solution {\n    public int[] twoSum(int[] nums, int target) {\n        Map<Integer, Integer> map = new HashMap<>();\n        for (int i = 0; i < nums.length; i++) {\n            int complement = target - nums[i];\n            if (map.containsKey(complement)) {\n                return new int[] { map.get(complement), i };\n            }\n            map.put(nums[i], i);\n        }\n        return new int[] { -1, -1 };\n    }\n}");
        submission2.setLanguage("java");
        submission2.setStatus("编译错误");
        submission2.setCompileError("缺少main方法");
        submission2.setSubmissionType("practice");
        submission2.setEnableO2("否");
        submission2.setSubmissionTime(new Date());
        submissionMap.put(submission2.getSubmissionId(), submission2);

        OjSubmission submission3 = new OjSubmission();
        submission3.setSubmissionId("S1003");
        submission3.setUserId("student003");
        submission3.setProblemId("P1002");
        submission3.setCode("def longestPalindrome(s):\n    if not s:\n        return \"\"\n    \n    start = 0\n    max_len = 1\n    \n    for i in range(len(s)):\n        # 奇数长度回文\n        left, right = i, i\n        while left >= 0 and right < len(s) and s[left] == s[right]:\n            if right - left + 1 > max_len:\n                start = left\n                max_len = right - left + 1\n            left -= 1\n            right += 1\n        \n        # 偶数长度回文\n        left, right = i, i + 1\n        while left >= 0 and right < len(s) and s[left] == s[right]:\n            if right - left + 1 > max_len:\n                start = left\n                max_len = right - left + 1\n            left -= 1\n            right += 1\n    \n    return s[start:start + max_len]");
        submission3.setLanguage("python");
        submission3.setStatus("已完成");
        submission3.setExecutionTime(45);
        submission3.setMemoryUsage(new BigDecimal("12.3"));
        submission3.setTestCasesPassed(8);
        submission3.setTotalTestCases(10);
        submission3.setScore(new BigDecimal("12"));
        submission3.setSubmissionType("homework");
        submission3.setEnableO2("否");
        submission3.setSubmissionTime(new Date());
        submission3.setJudgedTime(new Date());
        submissionMap.put(submission3.getSubmissionId(), submission3);
    }

    /**
     * 查询OJ题目
     * 
     * @param problemId OJ题目主键
     * @return OJ题目
     */
    @Override
    public OjProblem selectProblemById(String problemId)
    {
        return problemMap.get(problemId);
    }

    /**
     * 查询OJ题目列表
     * 
     * @param keyword 搜索关键词
     * @param difficulty 难度等级
     * @param category 题目类别
     * @param status 完成状态
     * @return OJ题目集合
     */
    @Override
    public List<OjProblem> selectProblemList(String keyword, String difficulty, String category, String status)
    {
        List<OjProblem> result = new ArrayList<>();
        for (OjProblem problem : problemMap.values()) {
            if (keyword != null && !problem.getProblemName().contains(keyword)) {
                continue;
            }
            if (difficulty != null && !difficulty.equals(problem.getDifficulty())) {
                continue;
            }
            if (category != null && !category.equals(problem.getCategory())) {
                continue;
            }
            if (status != null && !status.equals(problem.getStatus())) {
                continue;
            }
            result.add(problem);
        }
        return result;
    }

    /**
     * 新增OJ题目
     * 
     * @param ojProblem OJ题目
     * @return 结果
     */
    @Override
    public int insertProblem(OjProblem ojProblem)
    {
        if (ojProblem.getProblemId() == null) {
            ojProblem.setProblemId("P" + System.currentTimeMillis());
        }
        if (ojProblem.getCreatedAt() == null) {
            ojProblem.setCreatedAt(new Date());
        }
        if (ojProblem.getUpdatedAt() == null) {
            ojProblem.setUpdatedAt(new Date());
        }
        problemMap.put(ojProblem.getProblemId(), ojProblem);
        return 1;
    }

    /**
     * 修改OJ题目
     * 
     * @param ojProblem OJ题目
     * @return 结果
     */
    @Override
    public int updateProblem(OjProblem ojProblem)
    {
        if (problemMap.containsKey(ojProblem.getProblemId())) {
            ojProblem.setUpdatedAt(new Date());
            problemMap.put(ojProblem.getProblemId(), ojProblem);
            return 1;
        }
        return 0;
    }

    /**
     * 批量删除OJ题目
     * 
     * @param problemIds 需要删除的OJ题目主键集合
     * @return 结果
     */
    @Override
    public int deleteProblemByProblemIds(String problemIds)
    {
        String[] ids = problemIds.split(",");
        int count = 0;
        for (String id : ids) {
            if (problemMap.remove(id.trim()) != null) {
                count++;
            }
        }
        return count;
    }

    /**
     * 删除OJ题目信息
     * 
     * @param problemId OJ题目主键
     * @return 结果
     */
    @Override
    public int deleteProblemByProblemId(String problemId)
    {
        return problemMap.remove(problemId) != null ? 1 : 0;
    }

    /**
     * 查询OJ代码提交
     * 
     * @param submissionId OJ代码提交主键
     * @return OJ代码提交
     */
    @Override
    public OjSubmission selectSubmissionById(String submissionId)
    {
        return submissionMap.get(submissionId);
    }

    /**
     * 查询OJ代码提交列表
     * 
     * @param userId 用户ID
     * @param problemId 题目ID
     * @param status 提交状态
     * @param language 编程语言
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return OJ代码提交集合
     */
    @Override
    public List<OjSubmission> selectSubmissionList(String userId, String problemId, String status, String language, String startTime, String endTime)
    {
        List<OjSubmission> result = new ArrayList<>();
        for (OjSubmission submission : submissionMap.values()) {
            if (userId != null && !userId.equals(submission.getUserId())) {
                continue;
            }
            if (problemId != null && !problemId.equals(submission.getProblemId())) {
                continue;
            }
            if (status != null && !status.equals(submission.getStatus())) {
                continue;
            }
            if (language != null && !language.equals(submission.getLanguage())) {
                continue;
            }
            // 时间范围过滤可以在这里添加
            result.add(submission);
        }
        return result;
    }

    /**
     * 新增OJ代码提交
     * 
     * @param ojSubmission OJ代码提交
     * @return 结果
     */
    @Override
    public int insertSubmission(OjSubmission ojSubmission)
    {
        if (ojSubmission.getSubmissionId() == null) {
            ojSubmission.setSubmissionId("S" + System.currentTimeMillis());
        }
        if (ojSubmission.getSubmissionTime() == null) {
            ojSubmission.setSubmissionTime(new Date());
        }
        submissionMap.put(ojSubmission.getSubmissionId(), ojSubmission);
        return 1;
    }

    /**
     * 修改OJ代码提交
     * 
     * @param ojSubmission OJ代码提交
     * @return 结果
     */
    @Override
    public int updateSubmission(OjSubmission ojSubmission)
    {
        if (submissionMap.containsKey(ojSubmission.getSubmissionId())) {
            submissionMap.put(ojSubmission.getSubmissionId(), ojSubmission);
            return 1;
        }
        return 0;
    }

    /**
     * 批量删除OJ代码提交
     * 
     * @param submissionIds 需要删除的OJ代码提交主键集合
     * @return 结果
     */
    @Override
    public int deleteSubmissionBySubmissionIds(String submissionIds)
    {
        String[] ids = submissionIds.split(",");
        int count = 0;
        for (String id : ids) {
            if (submissionMap.remove(id.trim()) != null) {
                count++;
            }
        }
        return count;
    }

    /**
     * 删除OJ代码提交信息
     * 
     * @param submissionId OJ代码提交主键
     * @return 结果
     */
    @Override
    public int deleteSubmissionBySubmissionId(String submissionId)
    {
        return submissionMap.remove(submissionId) != null ? 1 : 0;
    }

    /**
     * 获取题目测试用例
     */
    @Override
    public List<Map<String, Object>> getProblemTestCases(String problemId)
    {
        List<Map<String, Object>> testCases = new ArrayList<>();
        
        if ("P1001".equals(problemId)) {
            Map<String, Object> test1 = new HashMap<>();
            test1.put("input", "1 2");
            test1.put("output", "3");
            testCases.add(test1);
            
            Map<String, Object> test2 = new HashMap<>();
            test2.put("input", "100 200");
            test2.put("output", "300");
            testCases.add(test2);
        }
        
        return testCases;
    }

    /**
     * 运行代码
     */
    @Override
    public Map<String, Object> runCode(String problemId, String code, String language, String input, Boolean enableO2)
    {
        Map<String, Object> result = new HashMap<>();
        result.put("status", "success");
        result.put("executionTime", 15);
        result.put("memoryUsage", new java.math.BigDecimal("2.5"));
        result.put("testCases", 2);
        result.put("totalTestCases", 2);
        
        List<Map<String, Object>> testResults = new ArrayList<>();
        Map<String, Object> test1 = new HashMap<>();
        test1.put("status", "passed");
        test1.put("input", "1 2");
        test1.put("expectedOutput", "3");
        test1.put("actualOutput", "3");
        testResults.add(test1);
        
        Map<String, Object> test2 = new HashMap<>();
        test2.put("status", "passed");
        test2.put("input", "100 200");
        test2.put("expectedOutput", "300");
        test2.put("actualOutput", "300");
        testResults.add(test2);
        
        result.put("testResults", testResults);
        return result;
    }

    /**
     * 提交代码
     */
    @Override
    public String submitCode(String problemId, String code, String language, Boolean enableO2, String submissionType)
    {
        String submissionId = "S" + submissionIdCounter++;
        
        OjSubmission submission = new OjSubmission();
        submission.setSubmissionId(submissionId);
        submission.setProblemId(problemId);
        submission.setCode(code);
        submission.setLanguage(language);
        submission.setStatus("评测中");
        submission.setSubmissionType(submissionType);
        submission.setEnableO2(enableO2 ? "1" : "0");
        submission.setSubmissionTime(new Date());
        
        submissionMap.put(submissionId, submission);
        
        // 模拟异步评测
        new Thread(() -> {
            try {
                Thread.sleep(2000); // 模拟评测时间
                submission.setStatus("已完成");
                submission.setJudgedTime(new Date());
                submission.setExecutionTime(15);
                submission.setMemoryUsage(new java.math.BigDecimal("2.5"));
                submission.setTestCasesPassed(2);
                submission.setTotalTestCases(2);
                submission.setScore(new java.math.BigDecimal("10"));
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
        
        return submissionId;
    }

    /**
     * 获取提交结果
     */
    @Override
    public Map<String, Object> getSubmissionResult(String submissionId)
    {
        OjSubmission submission = submissionMap.get(submissionId);
        if (submission == null) {
            return null;
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("submissionId", submission.getSubmissionId());
        result.put("status", submission.getStatus());
        result.put("executionTime", submission.getExecutionTime());
        result.put("memoryUsage", submission.getMemoryUsage());
        result.put("testCases", submission.getTestCasesPassed());
        result.put("totalTestCases", submission.getTotalTestCases());
        result.put("score", submission.getScore());
        
        return result;
    }

    /**
     * 获取提交统计
     */
    @Override
    public Map<String, Object> getSubmissionStats(String userId, String timeRange)
    {
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalSubmissions", submissionMap.size());
        stats.put("acceptedSubmissions", submissionMap.values().stream()
            .filter(s -> "已完成".equals(s.getStatus()) && s.getScore() != null && s.getScore().compareTo(java.math.BigDecimal.ZERO) > 0)
            .count());
        stats.put("averageScore", 85.5);
        return stats;
    }

    /**
     * 获取支持的编程语言
     */
    @Override
    public List<Map<String, Object>> getSupportedLanguages()
    {
        List<Map<String, Object>> languages = new ArrayList<>();
        
        Map<String, Object> cpp = new HashMap<>();
        cpp.put("name", "C++");
        cpp.put("value", "cpp");
        cpp.put("extension", ".cpp");
        languages.add(cpp);
        
        Map<String, Object> java = new HashMap<>();
        java.put("name", "Java");
        java.put("value", "java");
        java.put("extension", ".java");
        languages.add(java);
        
        Map<String, Object> python = new HashMap<>();
        python.put("name", "Python");
        python.put("value", "python");
        python.put("extension", ".py");
        languages.add(python);
        
        return languages;
    }

    /**
     * 获取语言配置
     */
    @Override
    public Map<String, Object> getLanguageConfig(String language)
    {
        Map<String, Object> config = new HashMap<>();
        config.put("language", language);
        config.put("compiler", "gcc");
        config.put("version", "11.2.0");
        config.put("flags", "-O2 -std=c++17");
        return config;
    }

    /**
     * 获取题目排行榜
     */
    @Override
    public List<Map<String, Object>> getProblemRanking(String problemId, String rankingType, Integer limit)
    {
        List<Map<String, Object>> ranking = new ArrayList<>();
        for (int i = 0; i < Math.min(limit, 10); i++) {
            Map<String, Object> rank = new HashMap<>();
            rank.put("rank", i + 1);
            rank.put("userId", "user" + (i + 1));
            rank.put("username", "用户" + (i + 1));
            rank.put("score", 100 - i * 5);
            rank.put("executionTime", 15 + i);
            ranking.add(rank);
        }
        return ranking;
    }

    /**
     * 获取用户解题进度
     */
    @Override
    public Map<String, Object> getUserProgress(String userId)
    {
        Map<String, Object> progress = new HashMap<>();
        progress.put("totalProblems", problemMap.size());
        progress.put("solvedProblems", 2);
        progress.put("attemptedProblems", 3);
        progress.put("successRate", 66.7);
        return progress;
    }

    /**
     * 获取题目分类
     */
    @Override
    public List<Map<String, Object>> getProblemCategories()
    {
        List<Map<String, Object>> categories = new ArrayList<>();
        
        Map<String, Object> cat1 = new HashMap<>();
        cat1.put("id", "1");
        cat1.put("name", "基础算法");
        categories.add(cat1);
        
        Map<String, Object> cat2 = new HashMap<>();
        cat2.put("id", "2");
        cat2.put("name", "数据结构");
        categories.add(cat2);
        
        return categories;
    }

    /**
     * 获取题目标签
     */
    @Override
    public List<Map<String, Object>> getProblemTags()
    {
        List<Map<String, Object>> tags = new ArrayList<>();
        
        Map<String, Object> tag1 = new HashMap<>();
        tag1.put("id", "1");
        tag1.put("name", "动态规划");
        tags.add(tag1);
        
        Map<String, Object> tag2 = new HashMap<>();
        tag2.put("id", "2");
        tag2.put("name", "贪心算法");
        tags.add(tag2);
        
        return tags;
    }

    /**
     * 获取相关题目推荐
     */
    @Override
    public List<Map<String, Object>> getRelatedProblems(String problemId, String userId, Integer limit)
    {
        List<Map<String, Object>> problems = new ArrayList<>();
        for (int i = 0; i < Math.min(limit, 3); i++) {
            Map<String, Object> problem = new HashMap<>();
            problem.put("id", "P" + (2000 + i));
            problem.put("name", "相关题目" + (i + 1));
            problem.put("difficulty", "中等");
            problems.add(problem);
        }
        return problems;
    }

    /**
     * 获取题目讨论
     */
    @Override
    public List<Map<String, Object>> getProblemDiscussions(String problemId)
    {
        List<Map<String, Object>> discussions = new ArrayList<>();
        Map<String, Object> discussion = new HashMap<>();
        discussion.put("id", "1");
        discussion.put("title", "这道题目的解法讨论");
        discussion.put("content", "这道题目可以使用动态规划来解决...");
        discussion.put("author", "user1");
        discussions.add(discussion);
        return discussions;
    }

    /**
     * 添加题目讨论
     */
    @Override
    public int addProblemDiscussion(String problemId, String title, String content, String type)
    {
        // 实际项目中应该保存到数据库
        return 1;
    }

    /**
     * 获取题目解决方案
     */
    @Override
    public List<Map<String, Object>> getProblemSolutions(String problemId, String language)
    {
        List<Map<String, Object>> solutions = new ArrayList<>();
        Map<String, Object> solution = new HashMap<>();
        solution.put("id", "1");
        solution.put("language", language);
        solution.put("code", "// 示例代码\nint main() {\n    return 0;\n}");
        solution.put("author", "user1");
        solutions.add(solution);
        return solutions;
    }

    /**
     * 获取代码模板
     */
    @Override
    public Map<String, Object> getCodeTemplate(String language, String problemType)
    {
        Map<String, Object> template = new HashMap<>();
        template.put("language", language);
        template.put("problemType", problemType);
        template.put("code", "// " + language + " 代码模板\n// 题目类型: " + problemType);
        return template;
    }

    /**
     * 保存代码草稿
     */
    @Override
    public int saveCodeDraft(String problemId, String code, String language, String userId)
    {
        // 实际项目中应该保存到数据库
        return 1;
    }

    /**
     * 获取代码草稿
     */
    @Override
    public Map<String, Object> getCodeDraft(String problemId, String userId)
    {
        Map<String, Object> draft = new HashMap<>();
        draft.put("problemId", problemId);
        draft.put("userId", userId);
        draft.put("code", "// 草稿代码");
        draft.put("language", "cpp");
        return draft;
    }

    /**
     * 获取代码草稿列表
     */
    @Override
    public List<Map<String, Object>> getCodeDraftList(String userId)
    {
        List<Map<String, Object>> drafts = new ArrayList<>();
        Map<String, Object> draft = new HashMap<>();
        draft.put("id", "1");
        draft.put("problemId", "P1001");
        draft.put("language", "cpp");
        draft.put("updateTime", new Date());
        drafts.add(draft);
        return drafts;
    }

    /**
     * 删除代码草稿
     */
    @Override
    public int deleteCodeDraft(String draftId)
    {
        // 实际项目中应该从数据库删除
        return 1;
    }

    /**
     * 获取系统状态
     */
    @Override
    public Map<String, Object> getSystemStatus()
    {
        Map<String, Object> status = new HashMap<>();
        status.put("status", "正常");
        status.put("uptime", "24小时");
        status.put("activeUsers", 156);
        status.put("totalSubmissions", submissionMap.size());
        return status;
    }

    /**
     * 获取系统配置
     */
    @Override
    public Map<String, Object> getSystemConfig()
    {
        Map<String, Object> config = new HashMap<>();
        config.put("maxExecutionTime", 5000);
        config.put("maxMemoryUsage", 512);
        config.put("supportedLanguages", Arrays.asList("cpp", "java", "python"));
        return config;
    }

    /**
     * 获取用户OJ统计信息
     */
    @Override
    public Map<String, Object> getUserOjStats(String userId)
    {
        Map<String, Object> stats = new HashMap<>();
        stats.put("userId", userId);
        stats.put("totalSubmissions", submissionMap.size());
        stats.put("acceptedSubmissions", 2);
        stats.put("averageScore", 85.5);
        stats.put("ranking", 15);
        return stats;
    }

    /**
     * 获取OJ排行榜
     */
    @Override
    public List<Map<String, Object>> getOjRanking(String rankingType, String timeRange, Integer limit)
    {
        List<Map<String, Object>> ranking = new ArrayList<>();
        for (int i = 0; i < Math.min(limit, 20); i++) {
            Map<String, Object> rank = new HashMap<>();
            rank.put("rank", i + 1);
            rank.put("userId", "user" + (i + 1));
            rank.put("username", "用户" + (i + 1));
            rank.put("score", 1000 - i * 10);
            rank.put("solvedProblems", 50 - i);
            ranking.add(rank);
        }
        return ranking;
    }
} 